package com.aliengen.thingple.driverapp.ui.fragments;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.Toast;

import com.aliengen.thingple.beep.DevBeep;
import com.aliengen.thingple.cmc168mwithservice.Common;
import com.aliengen.thingple.driverapp.R;
import com.aliengen.thingple.driverapp.data.exception.InvalidTagException;
import com.aliengen.thingple.driverapp.data.local.Preferences;
import com.aliengen.thingple.driverapp.data.models.Tag;
import com.aliengen.thingple.driverapp.device.CMCHandler;
import com.aliengen.thingple.driverapp.service.HandsetApplication;

/**
 * This class is part of the Thingple mobile application for the CMC168 Handheld reader.
 *
 * Copyright AlienGen Limited 2016. All rights reserved.
 *
 * @author Timothé Mermet-Buffet <tim@aliengen.com>
 */
public class DialogRFIDReadingFragment  extends DialogFragment {
    private ReadTagThread thread;
    private ReadingDialogListener mListener;

    HandsetApplication mApplication;
    Activity mActivity;

    public Boolean isReading = true;

    public interface ReadingDialogListener {
        public void onReadingNew(Tag tag);
        public Tag getTagFromBytes(byte[] tag) throws InvalidTagException;
    }

    class ReadTagThread extends Thread {
        @Override
        public void run(){
            Log.i("ReadTagThread", "Start!");
            isReading = true;

            mApplication.mService.device.startInventory();
            do {
                try {
                    Thread.sleep(10L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } while(mListener == null);

            while(isReading == true && mListener != null) {
                try{
                    sleep(100);
                }
                catch (InterruptedException e){e.printStackTrace();}

                try {
                    int cnt = mApplication.mService.device.getSize();
                    String epc = "";
                    Tag tag = null;

                    for(int j = 0;j < cnt; j++) {
                        epc = mApplication.mService.device.getItem();

                        byte[] epc_b = new byte[16];
                        Common.hexStr2Bytes(epc, epc_b, 0, 16);

                        Log.i("ReadTagThread", "Read epc: " + epc);

                        if(mListener != null)
                        {
                            try {
                                tag = mListener.getTagFromBytes(epc_b);
                                showToast(tag.toString());
                                DevBeep.PlayOK();

                                Log.i("ReadTagThread", "Valid tag detected!");
                                /* Empty the list of readed tags. */
                                //while(mApplication.mService.device.getItem() != null);

                                isReading = false;
                                mListener.onReadingNew(tag);
                                break;
                            } catch(InvalidTagException e)
                            {
                                Log.w("ReadTagThread", e.getMessage());
                                //showToast(e.getMessage());
                            }
                        }
                        else
                        {
                            Log.i("ReadTagThread", "mListener null...");
                        }
                    }
                    //mApplication.mService.device.resetItems();
                    try {sleep(50);} catch (InterruptedException e) {}

                    /**
                     * Dirty part to catch the events of the trigger
                     */
                /*
                    mApplication.mService.device.stopInventory();
                    try {sleep(250);} catch (InterruptedException e) {}
                    mApplication.mService.device.startInventory();
                    */
                }
                catch(Exception e)
                {
                    Log.i("ReadTagThread", e.toString());
                }
            }
            mApplication.mService.device.stopInventory();
            mApplication.mService.device.resetItems();
            Log.i("ReadTagThread", "Stop!");
        }
    }

    public void init(Activity activity)
    {
        mActivity = activity;
        mApplication = (HandsetApplication) mActivity.getApplication();

        mApplication.getHandler().setActivity(activity);

        mApplication.getHandler().setOnEventListener(new CMCHandler.OnEventListener() {
            @Override
            public void onPressDown() {
                startReading();
            }

            @Override
            public void onPressUp() {
                stopReading();
            }

            @Override
            public void onReceiveData() {
            }

            @Override
            public void onRead(String data) {
            }

            @Override
            public void onReadFailed() {
            }

            @Override
            public void onWrite() {
            }

            @Override
            public void onWriteFailed() {
            }

            @Override
            public void onTagSelected() {
            }

            @Override
            public void onTagSelectFailed() {

            }
        });

        int power = Preferences.get(Preferences.SHARE_SINGLE_READ_POWER, 5);
        mApplication.mService.device.setPower(power);
    }

    public void startReading()
    {
        Log.i("DialogRFIDReading", "startReading()");

        if(!this.isVisible() && !this.isAdded()) {
            if(thread != null) {
                isReading = false;
            }

            try {
                Thread.sleep(200);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }

            thread = new ReadTagThread();
            thread.start();

            this.show(mActivity.getFragmentManager(), "IdentityReading");
            Log.i("DialogRFIDReading", "Show!");
        }
    }

    public void stopReading() {
        Log.i("DialogRFIDReading", "stopReading()");
            if(thread != null) {
                isReading = false;
            }

            try {
                Thread.sleep(200);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }

            try {
                // TODO: Check when a dialog can be dismiss.
                this.dismiss();
                Log.i("DialogRFIDReading", "Dismissed!");
            }catch(Exception e)
            {
                e.printStackTrace();
            }
    }

    public void showToast(final CharSequence message) {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(mActivity.getApplicationContext(), message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        LayoutInflater inflater = getActivity().getLayoutInflater();
        builder.setView(inflater.inflate(R.layout.fragment_dialog_reading, null))
                .setTitle(R.string.reading)
                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        stopReading();
                    }
                });

        return builder.create();
    }

    @Override
    public void onAttach(Activity context) {
        super.onAttach(context);
        if (context instanceof ReadingDialogListener) {
            mListener = (ReadingDialogListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }
}
